﻿using System;
using System.Collections.Generic;
using System.Text;
using log4net.Appender;
using System.IO;
using log4net.Filter;
using log4net.Layout;
using log4net.Repository.Hierarchy;
using log4net.Core;

namespace Pink.Scheduler.Shared
{
	/// <summary>
	/// Класс, создание которого настраивает для всех нижележащих вызовов логгирование
	/// в файл.
	/// </summary>
	internal class FileLoggingContext : IDisposable
	{
		const string propertyName = "FileLoggingContext";
		private FileAppender appender;

		/// <summary>
		/// Перенаправить логгинг ниже по стеку в указанный файл.
		/// </summary>
		/// <param name="fileName">Имя файла</param>
		/// <param name="pattern">Паттерн для вывода текста</param>
		public FileLoggingContext(string fileName, string pattern)
		{
			appender = new FileAppender();
			appender.File = fileName;
			appender.Layout = new PatternLayout(pattern);
			appender.AppendToFile = false;
			string filterValue = Path.GetFullPath(fileName);
			PropertyFilter fileFilter = new PropertyFilter();
			fileFilter.Key = propertyName;
			fileFilter.StringToMatch = filterValue;
			appender.AddFilter(fileFilter);
			DenyAllFilter deny = new DenyAllFilter();
			appender.AddFilter(deny);
			appender.ActivateOptions();
			// аппендер ловит только записи с указанным значением свойства
			log4net.LogicalThreadContext.Properties[propertyName] = filterValue;
			GetRootLogger().AddAppender(appender);
		}
		/// <summary>
		/// Разрегистрироваться в log4net и освободить файл.
		/// </summary>
		public void Dispose()
		{
			Logger l = GetRootLogger();
			if (l.Appenders.Contains(appender))
				l.RemoveAppender(appender);
			log4net.LogicalThreadContext.Properties.Remove(propertyName);
			appender.Close();
			appender = null;
		}

		private Logger GetRootLogger()
		{
			Hierarchy h = (Hierarchy)log4net.LogManager.GetRepository();
			return h.Root;
		}
	}
}
